<!DOCTYPE html>
<html lang="en">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Porting to GCC 7</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>
<h1>Porting to GCC 7</h1>

<p>
The GCC 7 release series differs from previous GCC releases in
<a href="changes.html">a number of ways</a>. Some of
these are a result of bug fixing, and some old behaviors have been
intentionally changed in order to support new standards, or relaxed
in standards-conforming ways to facilitate compilation or run-time
performance.  Some of these changes are not visible to the naked eye
and will not cause problems when updating from older versions.
</p>

<p>
However, some of these changes are user visible and can cause grief when
porting to GCC 7. This document is an effort to identify common issues
and provide solutions. Let us know if you have suggestions for improvements!
</p>


<h2 id="cxx">C++ language issues</h2>

<h3 id="hypothetical-instantiation">Stricter rules when using templates</h3>

<p>
GCC 7 no longer accepts various ill-formed constructs involving the use
of templates. The C++ standard says:
</p>

<blockquote>
14.6/8: "If a hypothetical instantiation of a template immediately
following its definition would be ill-formed due to a construct that
does not depend on a template parameter, the program is ill-formed; no
diagnostic is required.  If the interpretation of such a construct in
the hypothetical instantiation is different from the interpretation of
the corresponding construct in any actual instantiation of the
template, the program is ill-formed; no diagnostic is required."
</blockquote>

<p>
As a consequence, the following examples are invalid and G++ will either
no longer compile them, or will warn.  G++ used to treat
<code>this-&gt;<i>member</i></code>, where <i>member</i> has
a non-dependent type, as type-dependent and no longer does.
</p>

<pre><code>
struct C;
struct A {
  C fn1();
};
template &lt;typename&gt; class B : A {
  void fn2() { fn1().x; }
};
</code></pre>
results in
<blockquote><pre>
<span class="boldmagenta">warning:</span> invalid use of incomplete type <b>'struct C'</b>
</pre></blockquote>

<pre><code>
struct A {
  int x;
};
template &lt;typename&gt; struct B : A {
  void fn1() { foo (this-&gt;x); }
};
</code></pre>
results in
<blockquote><pre>
<span class="boldred">error:</span> there are no arguments to <b>'foo'</b> that depend on a template parameter, so a declaration of <b>'foo'</b> must be available
</pre></blockquote>

<pre><code>
struct A {
  void* a;
};
template &lt;typename&gt; class B : A {
  void fn1() { this-&gt;a[0]; }
};
</code></pre>
results in
<blockquote><pre>
<span class="boldred">error:</span> <b>'void*'</b> is not a pointer-to-object type
</pre></blockquote>
because there is no instantiation of that template that can be valid; it
will always dereference a <code>void*</code>.

<h3 id="conversion-op-mangling">Mangling change for conversion operators</h3>

<p>
GCC 7 changes the name mangling for a conversion operator that returns a type
using the <code>abi_tag</code> attribute, see
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71712">PR 71712</a>.
This affects code that has conversions to <code>std::string</code>,
for example:
</p>

<pre><code>struct A {
  operator std::string() const;
};
</code></pre>

<p>
Code using such conversions might fail to link if some objects are compiled
with GCC 7 and some are compiled with older releases.
</p>

<h3 id="null-pointer-constants">Null pointer constants</h3>

<p>
When compiling as C++11 or later, GCC 7 follows the revised definition of a
<em>null pointer constant</em>. This means conversions to pointers from other
types of constant (such as character literals and boolean literals) are now
rejected.
</p>

<pre><code>void* f() {
  char* p = '\0';
  return false;
}
</code></pre>

      <blockquote><pre>
<span class="boldred">error:</span> invalid conversion from <b>'char'</b> to <b>'char*'</b> [<span class="boldred">-fpermissive</span>]
   char* p = <span class="boldred">'\0'</span>;
             <span class="boldred">^~~~</span>
<span class="boldred">error:</span> cannot convert <b>'bool'</b> to <b>'void*'</b> in return
   return <span class="boldred">false</span>;
          <span class="boldred">^~~~~</span>
</pre></blockquote>

<p>
Such code should be fixed to use a valid null pointer constant such as
<code>0</code> or <code>nullptr</code>. Care should be taken when fixing
invalid uses of <code>'\0'</code> as a pointer, as it may not be clear whether
the intention was to create a null pointer (<code>p = 0;</code>), to create an
empty string (<code>p = "";</code>), or to write a null terminator to the
string (<code>*p = '\0';</code>).
</p>

<h3 id="header-dep-changes">Header dependency changes</h3>

<p>
Several C++ Standard Library headers have been changed to no longer include
the <code>&lt;functional&gt;</code> header.
As such, C++ programs that used components defined in
<code>&lt;functional&gt;</code> without explicitly including that header
will no longer compile.
</p>
<p>
Previously components such as <code>std::bind</code>
and <code>std::function</code> were implicitly defined after including
unrelated headers such as <code>&lt;memory&gt;</code>,
<code>&lt;future&gt;</code>, <code>&lt;mutex&gt;</code>, and
<code>&lt;regex&gt;</code>.
Correct code should <code>#include &lt;functional&gt;</code> to define them.
</p>

<h3 id="cmath">Additional overloads of <code>abs</code></h3>

<p>
As required by the latest C++ draft, all overloads of the <code>abs</code>
function are declared by including either of
<code>&lt;cstdlib&gt;</code> or <code>&lt;cmath&gt;</code>
(and correspondingly by either of <code>&lt;stdlib.h&gt;</code> or
<code>&lt;math.h&gt;</code>). Previously <code>&lt;cmath&gt;</code> only
declared the overloads for floating-point types, and
<code>&lt;cstdlib&gt;</code> only declared the overloads for integral types.
</p>

<p>
As a result of this change, code which overloads <code>abs</code> may no longer
compile if the custom overloads conflict with one of the additional overloads
in the standard headers. For example, this will not compile:
</p>

<pre><code>#include &lt;stdlib.h&gt;
float abs(float x) { return x &lt; 0 ? -x : x; }
</code></pre>

<p>
The solution is to use the standard functions, not define conflicting
overloads. For portability to previous versions of GCC and other
implementations the <code>abs(float)</code> function can be brought into
scope by including <code>&lt;cmath</code> and adding a using-declaration:
</p>

<pre><code>#include &lt;stdlib.h&gt;
#include &lt;cmath&gt;    // ensure std::abs(float) is declared
using std::abs;
</code></pre>

<p>
Additionally, <a href="../gcc-6/porting_to.html#overloaded-abs">calling
<code>abs</code> with an argument of unsigned type</a> is now ill-formed after
inclusion of any standard <code>abs</code> overload.
</p>

<h3 id="ios-failure"><code>std::ios_base::failure</code></h3>

<p>
When iostream objects are requested to throw exceptions on stream buffer
errors, the type of exception thrown has changed to use the
<a href="../gcc-5/changes.html#libstdcxx">new libstdc++ ABI
introduced in GCC 5</a>. Code which does
<code>catch (const std::ios::failure&amp;)</code> or similar will not catch
the exception if it is built using the old ABI. To ensure the exception is
caught either compile the catch handler using the new ABI, or use a handler
of type <code>std::exception</code> (which will catch the old and new versions
of <code>std::ios_base::failure</code>) or a handler of type
<code>std::system_error</code>.
</p>

<h3 id="std-function-target">Changes to <code>std::function</code> constructed with <code>std::reference_wrapper</code></h3>

<p>
Prior to GCC 7 a <code>std::function</code> constructed with a
<code>std::reference_wrapper&lt;T&gt;</code> would unwrap the argument and
store a target of type <code>T</code>, and <code>target_type()</code> would
return <code>typeid(T)</code>. GCC 7 has been changed to match the behavior
of other implementations and not unwrap the argument. This means the target
will be a <code>std::reference_wrapper&lt;T&gt;</code> and
<code>target_type()</code> will return
<code>typeid(std::reference_wrapper&lt;T&gt;)</code>.
Code which depends on the target type may need to be adjusted appropriately.
</p>

<h3 id="shared_ptr-array">Changes for array support in <code>std::shared_ptr</code></h3>

<p>
The behavior of <code>std::shared_ptr&lt;T[]&gt;</code> and 
<code>std::shared_ptr&lt;T[N]&gt;</code> has changed to match the semantics
in the C++17 draft. Previously specializations of <code>std::shared_ptr</code>
for array types had unhelpful semantics and were hard to use correctly, so the
semantics have changed to match the C++17 behavior in GCC 7. Code which uses
specializations for array types may continue to work in C++11 and C++14 modes,
but not in C++17 mode. It is possible, although unlikely, that some valid uses
of array specializations will no longer work with GCC 7 even in C++11 or C++14
modes. All uses of array specialization should be adjusted to match the C++17
semantics which will be standardized soon. Code which only uses specializations
of <code>std::shared_ptr&lt;T&gt;</code> for non array-type is unaffected.
</p>

<h2 id="links">Links</h2>

<p>
Marek Polacek <a href="https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/7OS7EDKLZDY27C6777O6HE2QMF7YU3X7/">Fedora mass rebuild 2017 on x86_64</a>
</p>

</body>
</html>
